home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
icons
/
clrbut.zip
/
PDSCNTL.ZIP
/
PDSCNTL.C
< prev
next >
Wrap
Text File
|
1991-01-21
|
39KB
|
1,155 lines
/*
* PDSCNTL -- Dialog Editor / Custom Controls
* Copyright 1991, Professional Development Svcs, Dennis Cook
*
*/
#include <string.h>
#include <windows.h>
#include <custcntl.h>
#include "pdscntl.h"
#include "clrbuttn.h"
/* Function Prototypes */
void lstrncpy(LPSTR lpDest, LPSTR lpSrc, int n);
BOOL FAR PASCAL DrawLabel(HDC hDC, LPSTR lpLabelText, int nCount);
void ShowButtonDown(HANDLE hWnd);
void ShowButtonUp(HANDLE hWnd);
/* internal ColorButton function prototypes */
BOOL FAR PASCAL ColorButtonDlgFn( HWND, WORD, WORD, LONG );
LONG FAR PASCAL ColorButtonWndFn( HWND, WORD, WORD, LONG );
/* global static variables */
HANDLE hLibData;
HANDLE hLibInstance;
LPFNSTRTOID lpfnVerId;
LPFNIDTOSTR lpfnIdStr;
/* string for property lists */
#define IDFNLO "lpfnIdFnLo"
#define IDFNHI "lpfnIdFnHi"
/* general custom control definitions */
#define ID GetWindowWord( hWnd, GWW_ID )
#define PARENT GetWindowWord( hWnd, GWW_HWNDPARENT )
#define INSTANCE GetWindowWord( hWnd, GWW_HINSTANCE )
#define COLORBUTTONCLASS "ColorButton"
/* ColorButton specific definitions */
#define LABEL_EXTRA_SPACE 12
#define LABEL_LEN_OFFSET 8
#define LABEL_TEXT_OFFSET 10
#define COLORBUTTON_EXTRA 24
#define STRIP_BAD_DT_FLAG 0xFB7F
#define BUTTONISDOWN_FLAG 0x0001
#define BUTTONINFOCUS_FLAG 0x0002
#define USENORMALTEXT_FLAG 0x0004
#define CAPTUREON_FLAG 0x0008
#define MKCNTLON_FLAG 0x0010
#define BUTTONISUP_FLAG 0xFFFE
#define BUTTONNOFOCUS_FLAG 0xFFFD
#define USEGRAYEDTEXT_FLAG 0xFFFB
#define CAPTUREOFF_FLAG 0xFFF7
#define MKCNTLOFF_FLAG 0xFFEF
#define FACEBRUSH GetWindowWord( hWnd, 0 )
#define SHADOWBRUSH GetWindowWord( hWnd, 2 )
#define HILITEBRUSH GetWindowWord( hWnd, 4 )
#define LABELRGN GetWindowWord( hWnd, 6 )
#define SHADOWRGN GetWindowWord( hWnd, 8 )
#define HILITERGN GetWindowWord( hWnd, 10 )
#define NORMALTEXTRGB GetWindowLong( hWnd, 12 )
#define OTHERDATA GetWindowWord( hWnd, 16 )
#define USENORMALTEXT (GetWindowWord( hWnd, 18 ) & USENORMALTEXT_FLAG)
#define BUTTONISDOWN (GetWindowWord( hWnd, 18 ) & BUTTONISDOWN_FLAG)
#define BUTTONINFOCUS (GetWindowWord( hWnd, 18 ) & BUTTONINFOCUS_FLAG)
#define CAPTUREON (GetWindowWord( hWnd, 18 ) & CAPTUREON_FLAG)
#define MKCNTLON (GetWindowWord( hWnd, 18 ) & MKCNTLON_FLAG)
#define DRAWTEXTSTYLE GetWindowWord( hWnd, 20 )
#define LABELFONT GetWindowWord( hWnd, 22 )
#define SET_FACEBRUSH(x) SetWindowWord( hWnd, 0, x )
#define SET_SHADOWBRUSH(x) SetWindowWord( hWnd, 2, x )
#define SET_HILITEBRUSH(x) SetWindowWord( hWnd, 4, x )
#define SET_LABELRGN(x) SetWindowWord( hWnd, 6, x )
#define SET_SHADOWRGN(x) SetWindowWord( hWnd, 8, x )
#define SET_HILITERGN(x) SetWindowWord( hWnd, 10, x )
#define SET_NORMALTEXTRGB(x) SetWindowLong( hWnd, 12, x )
#define SET_OTHERDATA(x) SetWindowWord( hWnd, 16, x )
#define SET_USENORMALTEXT SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | USENORMALTEXT_FLAG) )
#define SET_USEGRAYEDTEXT SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & USEGRAYEDTEXT_FLAG) )
#define SET_BUTTONISDOWN SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | BUTTONISDOWN_FLAG) )
#define SET_BUTTONISUP SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & BUTTONISUP_FLAG) )
#define SET_BUTTONINFOCUS SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | BUTTONINFOCUS_FLAG) )
#define SET_BUTTONNOFOCUS SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & BUTTONNOFOCUS_FLAG) )
#define SET_CAPTUREON SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | CAPTUREON_FLAG) )
#define SET_CAPTUREOFF SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & CAPTUREOFF_FLAG) )
#define SET_MKCNTLON SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | MKCNTLON_FLAG) )
#define SET_MKCNTLOFF SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & MKCNTLOFF_FLAG) )
#define SET_DRAWTEXTSTYLE(x) SetWindowWord( hWnd, 20, x )
#define SET_LABELFONT(x) SetWindowWord( hWnd, 22, x )
/* ColorButton specific global variables */
HANDLE hDrawTextWnd;
HFONT hDefLabelFont;
HPEN hOutlinePen;
HBRUSH hDefFaceBrush, hDefHiliteBrush, hDefShadowBrush;
COLORREF crDefNormalText;
RECT rDrawLabel;
FARPROC lpfnDrawLabel;
/**/
/*
* LibMain( hInstance, wDataSegment, wHeapSize, lpszCmdLine ) : WORD
*
* hInstance library instance handle
* wDataSegment library data segment
* wHeapSize default heap size
* lpszCmdLine command line arguments
*
* LibMain is called by LibEntry, which is called by Windows when
* the DLL is loaded. The LibEntry routine is provided
* in the LIBENTRY.OBJ in the SDK Link Libraries disk. (The source
* LIBENTRY.ASM is also provided.)
*
* LibEntry initializes the DLL's heap, if a HEAPSIZE value is
* specified in the DLL's DEF file. Then LibEntry calls
* LibMain. The LibMain function below satisfies that call.
*
* LibMain performs all the initialization necessary to use the
* ColorButton user control. Included in this initialization is the
* registration of the ColorButton window class.
*
*/
int FAR PASCAL LibMain( HANDLE hInstance,
WORD wDataSegment,
WORD wHeapSize,
LPSTR lpszCmdLine )
{
HANDLE hClassStruct;
LPWNDCLASS lpClassStruct;
/* register ColorButton window if necessary */
if ( hLibInstance == NULL ) {
/* allocate memory for class structure */
hClassStruct = GlobalAlloc( GHND, (DWORD)sizeof(WNDCLASS) );
if ( hClassStruct ) {
/* lock it down */
lpClassStruct = (LPWNDCLASS)GlobalLock( hClassStruct );
if ( lpClassStruct ) {
/* define class attributes */
lpClassStruct->lpszClassName = (LPSTR)COLORBUTTONCLASS;
lpClassStruct->hCursor = LoadCursor( NULL, IDC_ARROW );
lpClassStruct->lpszMenuName = (LPSTR)NULL;
lpClassStruct->style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLOBALCLASS;
lpClassStruct->lpfnWndProc = ColorButtonWndFn;
lpClassStruct->hInstance = hInstance;
lpClassStruct->hIcon = NULL;
lpClassStruct->cbWndExtra = COLORBUTTON_EXTRA;
lpClassStruct->hbrBackground = (HBRUSH)(COLOR_WINDOW + 1 );
/* register ColorButton window class */
hLibInstance = ( RegisterClass(lpClassStruct) ) ? hInstance : NULL;
/* unlock structure */
GlobalUnlock( hClassStruct );
}
/* release class structure */
GlobalFree( hClassStruct );
// Create default GDI object
// First the outline pen
hOutlinePen = GetStockObject(BLACK_PEN);
// Now default text color & font
crDefNormalText = GetSysColor(COLOR_BTNTEXT);
hDefLabelFont = GetStockObject(SYSTEM_FONT);
// Now default brushes
hDefFaceBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
hDefShadowBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
hDefHiliteBrush = GetStockObject(WHITE_BRUSH);
lpfnDrawLabel = MakeProcInstance(DrawLabel, hInstance);
}
}
/* return result 1 = success; 0 = fail */
return( hLibInstance? 1:0 );
}
/**/
/****************************************************************************
FUNCTION: WEP(int)
PURPOSE: Performs cleanup tasks when the DLL is unloaded. WEP() is
called automatically by Windows when the DLL is unloaded
(no remaining tasks still have the DLL loaded). It is
strongly recommended that a DLL have a WEP() function,
even if it does nothing but return, as in this example.
*******************************************************************************/
VOID FAR PASCAL WEP (bSystemExit)
int bSystemExit;
{
FreeProcInstance(lpfnDrawLabel);
DeleteObject(hDefFaceBrush);
DeleteObject(hDefShadowBrush);
return;
}
/**/
/*
* ColorButtonInfo() : HANDLE
*
* This function returns a handle to a global block of memory that
* contains various information about the kinds of controls the library
* is capable of supporting. This data block can, for example, be used
* by the dialog editor when determining the capabilities of a particular
* control library.
*
* Note that this handle becomes the property of the caller once this
* function returns. This implies that the caller must call GlobalFree
* once it is finished with the data.
*
*/
HANDLE FAR PASCAL ColorButtonInfo()
{
HANDLE hCtlInfo;
LPCTLINFO lpCtlInfo;
/* allocate space for information structure */
hCtlInfo = GlobalAlloc( GHND, (DWORD)sizeof(CTLINFO) );
if ( hCtlInfo ) {
/* attempt to lock it down */
lpCtlInfo = (LPCTLINFO)GlobalLock( hCtlInfo );
if ( lpCtlInfo ) {
/* define the fixed portion of the structure */
lpCtlInfo->wVersion = 100;
lpCtlInfo->wCtlTypes = 1;
lstrcpy( lpCtlInfo->szClass, COLORBUTTONCLASS );
lstrcpy( lpCtlInfo->szTitle, "Sample User Control" );
/* define the variable portion of the structure */
lpCtlInfo->Type[0].wWidth = 25;
lpCtlInfo->Type[0].wHeight = 15;
lpCtlInfo->Type[0].dwStyle = WS_CHILD;
lstrcpy( lpCtlInfo->Type[0].szDescr, "ColorButton" );
/* unlock it */
GlobalUnlock( hCtlInfo );
}
else {
GlobalFree( hCtlInfo );
hCtlInfo = NULL;
}
}
/* return result */
return( hCtlInfo );
}
/**/
/*
* ColorButtonStyle( hWnd, hCtlStyle, lpfnVeriyId, lpfnGetIdStr ) : BOOL;
*
* hWnd handle to parent window
* hCtlStyle handle to control style
* lpfnVerifyId pointer to the VerifyId function from Dialog editor
* lpfnGetIdStr pointer to the GetIdStr functionn from Dialog editor
*
* This function enables the user to edit the style of a particular
* control provided. The current control style information is passed
* in using a handle to a control style data structure.
*
* This function returns this same handle (referencing updated
* information) if the dialog box is normally closed. A value of
* NULL is returned if the user cancelled the operation.
*
*/
BOOL FAR PASCAL ColorButtonStyle(HWND hWnd,
HANDLE hCtlStyle,
LPFNSTRTOID lpfnVerifyId,
LPFNIDTOSTR lpfnGetIdStr )
{
FARPROC lpDlgFn;
HANDLE hNewCtlStyle;
/* initialization */
hLibData = hCtlStyle;
lpfnVerId = lpfnVerifyId;
lpfnIdStr = lpfnGetIdStr;
/* display dialog box */
lpDlgFn = MakeProcInstance( (FARPROC)ColorButtonDlgFn, hLibInstance );
hNewCtlStyle = ( DialogBox(hLibInstance,"ColorButtonStyle",hWnd,lpDlgFn) ) ? hLibData : NULL;
FreeProcInstance( lpDlgFn );
/* return updated data block */
return( hNewCtlStyle );
}
/**/
/*
* ColorButtonFlags( wFlags, lpszString, wMaxString ) : WORD;
*
* wFlags class style flags
* lpszString class style string
* wMaxString maximum size of class style string
*
* This function translates the class style flags provided into a
* corresponding text string for output to an RC file. The general
* windows flags (contained in the low byte) are not interpreted,
* only those in the high byte.
*
* The value returned by this function is the library instance
* handle when sucessful, and NULL otherwise.
*
*/
WORD FAR PASCAL ColorButtonFlags(DWORD dwFlags,
LPSTR lpszString,
WORD wMaxString )
{
if (LOWORD(dwFlags) & BS_DEFPUSHBUTTON) {
lstrcpy(lpszString, "BS_DEFPUSHBUTTON | WS_TABSTOP");
return( 29 );
}
else {
lstrcpy(lpszString, "WS_TABSTOP");
return( 10 );
}
}
/**/
/*
* ColorButtonWndFn( hWnd, wMsg, wParam, lParam ) : LONG
*
* hWnd handle to ColorButton window
* wMsg message number
* wParam single word parameter
* lParam double word parameter
*
* This function is responsible for processing all the messages
* which relate to the ColorButton control window. Note how the
* code is written to avoid potential problems when re-entrancy
* ocurrs - this involves the use of extra bytes associated with
* the window data structure.
*
* The LONG value returned by this function is either a value
* returned by the internal handling of the message or by the
* default window procedure.
*
*/
LONG FAR PASCAL ColorButtonWndFn(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam )
{
/* local variables */
LONG lResult; /* temporary result variable */
/* initialization */
lResult = TRUE;
/* process message */
switch( wMsg ) {
case WM_CREATE:
// At this point we need to fill in the default extra bytes and
// get the window name from the createstruct \
// In addition to window extra bytes each button control will be
// allocated local heap space to hold the label text and label
// rectangle information. A handle to this space is put into the
// window extra bytes. Format for structure is as follows:
// Label rect left int
// Label rect top int
// Label rect right int
// Label rect bottom int
// Label text len word
// Label text [text len word] bytes
{
HANDLE hOtherData;
LPBYTE lpOtherData;
WORD wTextLen, wAllocBytes;
LPCREATESTRUCT lpcsData;
lpcsData = (LPCREATESTRUCT) lParam;
if ((lpcsData)->lpszName == NULL)
wTextLen = 0;
else
wTextLen = lstrlen((lpcsData)->lpszName);
// allocate space for information structure
wAllocBytes = wTextLen + LABEL_EXTRA_SPACE;
hOtherData = LocalAlloc( LHND, wAllocBytes );
if (hOtherData) {
if (wTextLen > 0) {
// attempt to lock it down
lpOtherData = (LPBYTE)LocalLock(hOtherData);
if (lpOtherData) {
// Store button label text info in allocated structure
lstrcpy((lpOtherData + LABEL_TEXT_OFFSET), (lpcsData)->lpszName);
(WORD) *(lpOtherData + LABEL_LEN_OFFSET) = wTextLen;
LocalUnlock(hOtherData);
}
}
// Store handle to structure, default brushes and colors
SET_OTHERDATA(hOtherData);
SET_FACEBRUSH(hDefFaceBrush);
SET_SHADOWBRUSH(hDefShadowBrush);
SET_HILITEBRUSH(hDefHiliteBrush);
SET_NORMALTEXTRGB(crDefNormalText);
SET_LABELFONT(hDefLabelFont);
SET_USENORMALTEXT;
SET_BUTTONISUP;
SET_BUTTONNOFOCUS;
SET_MKCNTLOFF;
SET_CAPTUREOFF;
SET_DRAWTEXTSTYLE((DT_CENTER | DT_WORDBREAK));
SET_HILITERGN(NULL);
SET_SHADOWRGN(NULL);
SET_LABELRGN(NULL);
//else post an error
}
//else post an error
}
break;
case WM_GETDLGCODE:
{
if (GetWindowLong(hWnd, GWL_STYLE) & BS_DEFPUSHBUTTON)
lResult = (LONG) DLGC_DEFPUSHBUTTON;
else
lResult = (LONG) DLGC_UNDEFPUSHBUTTON;
}
break;
case WM_SIZE:
// At this point we need to fill in the default extra bytes and
{
POINT pts[6];
int iLblHi, iLblWi, iTxtMaxWi, iTxtMaxHi;
RECT rRect;
LPRECT lprLabel;
LPBYTE lpLabelText;
HDC hDC;
HRGN hHiliteRgn, hShadowRgn, hLabelRgn;
HFONT hOldFont;
hHiliteRgn = HILITERGN;
hShadowRgn = SHADOWRGN;
hLabelRgn = LABELRGN;
if (hHiliteRgn)
DeleteObject(hHiliteRgn);
if (hHiliteRgn)
DeleteObject(hShadowRgn);
if (hHiliteRgn)
DeleteObject(hLabelRgn);
lprLabel = (LPRECT) LocalLock(OTHERDATA);
hDC = GetDC(hWnd);
hOldFont = SelectObject(hDC, LABELFONT);
GetClientRect(hWnd, &rRect);
// Create the hilite region
pts[0].x = pts[1].x = pts[1].y = pts[2].y = 1;
pts[4].x = pts[5].x = pts[3].y = pts[4].y = 3;
pts[0].y = rRect.bottom - 2;
pts[2].x = rRect.right - 2;
pts[3].x = rRect.right - 4;
pts[5].y = rRect.bottom - 4;
hHiliteRgn = CreatePolygonRgn((LPPOINT)&pts, 6, WINDING);
SET_HILITERGN(hHiliteRgn);
// Create the shadow region
pts[4].x = pts[5].x = rRect.right - 3;
pts[3].x = pts[5].y = 2;
pts[2].x = pts[0].y = 0;
pts[3].y = pts[4].y = rRect.bottom - 3;
pts[1].x = pts[0].x = rRect.right - 1;
pts[1].y = pts[2].y = rRect.bottom - 1;
hShadowRgn = CreatePolygonRgn((LPPOINT)&pts, 6, WINDING);
SET_SHADOWRGN(hShadowRgn);
// max size for label area is:
(lprLabel)->left = 6;
(lprLabel)->top = 6;
(lprLabel)->bottom = rRect.bottom - 6;
(lprLabel)->right = rRect.right - 6;
// Now test for minimum height of rectangle
lpLabelText = (LPBYTE) (lprLabel) + LABEL_TEXT_OFFSET;
if (!(lpLabelText[0] == NULL))
DrawText(hDC, lpLabelText, -1, lprLabel, ((DRAWTEXTSTYLE) | DT_CALCRECT));
// Make sure label rect does not exceed max size
iTxtMaxHi = rRect.bottom - 12;
iTxtMaxWi = rRect.right - 12;
iLblHi = (lprLabel)->bottom - (lprLabel)->top;
if (iLblHi > iTxtMaxHi)
iLblHi = iTxtMaxHi;
iLblWi = (lprLabel)->right - (lprLabel)->left;
if (iLblWi > iTxtMaxWi)
iLblWi = iTxtMaxWi;
// Reset label rect to center vertically
(lprLabel)->left = ((iTxtMaxWi - iLblWi) / 2) + 6;
(lprLabel)->top = ((iTxtMaxHi - iLblHi) / 2) + 6;
(lprLabel)->right = (lprLabel)->left + iLblWi;
(lprLabel)->bottom = (lprLabel)->top + iLblHi;
hLabelRgn = CreateRectRgn((lprLabel)->left,
(lprLabel)->top,
(lprLabel)->right,
(lprLabel)->bottom);
SET_LABELRGN(hLabelRgn);
SelectObject(hDC, hOldFont);
LocalUnlock(OTHERDATA);
ReleaseDC(hWnd, hDC);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rRect;
LPRECT lprLabel;
LPBYTE lpLabelText;
WORD wTextLen;
HDC hDC;
HPEN hOldPen;
HBRUSH hOldBrush;
HFONT hOldFont;
hDC = BeginPaint(hWnd, &ps);
// Before painting anything, notify parent to provide opportunity
// to set new brush and text colors (like pushbutton, nothing is
// is done with the return value.
SendMessage(PARENT, WM_CTLCOLOR, hDC, MAKELONG(hWnd, CTLCOLOR_BTN));
lprLabel = (LPRECT) LocalLock(OTHERDATA);
GetClientRect(hWnd, &rRect);
// Set text color and font
SetTextColor(hDC, NORMALTEXTRGB);
SetBkMode(hDC, TRANSPARENT);
hOldFont = SelectObject(hDC, (HFONT) LABELFONT);
// Create Button Outline and Fill with Face color
hOldPen = SelectObject(hDC, hOutlinePen);
hOldBrush = SelectObject(hDC, FACEBRUSH);
RoundRect(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom, 2, 2);
// Create button hilite & shadow
if (BUTTONISDOWN) {
FillRgn(hDC, HILITERGN, SHADOWBRUSH);
FillRgn(hDC, SHADOWRGN, FACEBRUSH);
}
else {
FillRgn(hDC, HILITERGN, HILITEBRUSH);
FillRgn(hDC, SHADOWRGN, SHADOWBRUSH);
}
// Display Label text
lpLabelText = (LPBYTE) (lprLabel) + LABEL_TEXT_OFFSET;
wTextLen = (WORD) *((LPBYTE) (lprLabel) + LABEL_LEN_OFFSET);
// When paint button in down position shift the label rect
if (BUTTONISDOWN)
OffsetRect(lprLabel, 2, 2);
if (!(lpLabelText[0] == NULL)) {
if (USENORMALTEXT) {
DrawText(hDC, lpLabelText, -1, lprLabel, DRAWTEXTSTYLE);
}
else {
HBRUSH hGrayedTextBrush;
POINT pt;
hGrayedTextBrush = CreateSolidBrush(NORMALTEXTRGB);
pt.x = pt.y = 0;
ClientToScreen(hWnd, &pt);
UnrealizeObject(hGrayedTextBrush);
SetBrushOrg(hDC, pt.x, pt.y);
hDrawTextWnd = hWnd;
rDrawLabel.left = rDrawLabel.top = 0;
rDrawLabel.right = (lprLabel)->right - (lprLabel)->left;
rDrawLabel.bottom = (lprLabel)->bottom - (lprLabel)->top;
GrayString(hDC, hGrayedTextBrush, lpfnDrawLabel,
(DWORD) lpLabelText, wTextLen,
(lprLabel)->left, (lprLabel)->top,
(lprLabel)->right - (lprLabel)->left,
(lprLabel)->bottom - (lprLabel)->top);
DeleteObject(hGrayedTextBrush);
}
}
if (BUTTONINFOCUS) {
rRect.left = (lprLabel)->left - 2;
rRect.top = (lprLabel)->top - 2;
rRect.right = (lprLabel)->right + 2;
rRect.bottom = (lprLabel)->bottom + 2;
DrawFocusRect(hDC, &rRect);
}
// After paint button in down position reset label rect value
if (BUTTONISDOWN)
OffsetRect(lprLabel, -2, -2);
SelectObject(hDC, hOldPen);
SelectObject(hDC, hOldBrush);
SelectObject(hDC, hOldFont);
LocalUnlock(OTHERDATA);
EndPaint(hWnd, &ps);
}
break;
case WM_SETFOCUS:
{
SET_BUTTONINFOCUS;
InvalidateRect(hWnd, NULL, FALSE);
}
break;
case WM_KILLFOCUS:
{
SET_BUTTONNOFOCUS;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
break;
case WM_ENABLE:
{
if (wParam) {
SET_USENORMALTEXT;
}
else {
SET_USEGRAYEDTEXT;
}
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
break;
case WM_KEYDOWN:
{
if (wParam == VK_SPACE) {
// if mouse does not have control
if (!(MKCNTLON)) {
//if the button is shown in the up position
if (!(BUTTONISDOWN)) {
ShowButtonDown(hWnd);
}
}
}
}
break;
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
{
if (!(CAPTUREON)) {
SET_CAPTUREON;
SetCapture(hWnd);
SET_MKCNTLON;
if (!(BUTTONISDOWN))
ShowButtonDown(hWnd);
}
}
break;
case WM_KEYUP:
{
if (wParam == VK_SPACE) {
// if mouse does not have control
if (!(MKCNTLON)) {
//if the button is shown in the down position
if ((BUTTONISDOWN)) {
ShowButtonUp(hWnd);
// send the parent window a button clicked command message
SendMessage(PARENT,WM_COMMAND,ID,MAKELONG(hWnd, BN_CLICKED));
}
}
}
}
break;
case WM_LBUTTONUP:
{
if (CAPTUREON) {
RECT rRect;
GetClientRect(hWnd, &rRect);
if (PtInRect(&rRect, MAKEPOINT(lParam))) {
// send the parent window a button clicked command message
SendMessage(PARENT,WM_COMMAND,ID,MAKELONG(hWnd, BN_CLICKED));
ShowButtonUp(hWnd);
}
SET_MKCNTLOFF;
SET_CAPTUREOFF;
ReleaseCapture();
}
}
break;
case WM_MOUSEACTIVATE:
{
SetFocus(hWnd);
}
break;
case WM_MOUSEMOVE:
{
RECT rRect;
GetClientRect(hWnd, &rRect);
// is the cursor in the button window
if (PtInRect(&rRect, MAKEPOINT(lParam))) {
// is the mouse button down
if (wParam & MK_LBUTTON) {
// is the button shown in the up position?
if (!(BUTTONISDOWN)) {
SET_BUTTONISDOWN;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
}
else { //cursor outside of the button window
// is the mouse button down
if (wParam & MK_LBUTTON) {
// is the button shown in the down position
if (BUTTONISDOWN) {
SET_BUTTONISUP;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
}
}
break;
case WM_SETTEXT:
{
WORD wNewTextLen, wCurrSize;
LPBYTE lpOtherData;
HANDLE hOtherData;
RECT rRect;
WORD wHi, wWi;
if (lParam == NULL)
wNewTextLen = 0;
else
wNewTextLen = lstrlen((LPSTR) lParam);
wCurrSize = LocalSize(OTHERDATA);
// If the new label string is larger than space currently allocated,
// then realloc more space
if ((wNewTextLen + LABEL_EXTRA_SPACE) > wCurrSize) {
hOtherData = LocalReAlloc(OTHERDATA,
(wNewTextLen + LABEL_EXTRA_SPACE),
LHND);
if (hOtherData)
SET_OTHERDATA(hOtherData);
else {
lResult = FALSE;
break;
}
}
lpOtherData = (LPBYTE)LocalLock(OTHERDATA);
if (lpOtherData) {
// Store button label text info in allocated structure
if (wNewTextLen)
lstrcpy((lpOtherData + LABEL_TEXT_OFFSET), (LPSTR) lParam);
else
*(lpOtherData + LABEL_TEXT_OFFSET) = NULL;
(WORD) *(lpOtherData + LABEL_LEN_OFFSET) = wNewTextLen;
LocalUnlock(OTHERDATA);
GetClientRect(hWnd, &rRect);
wHi = rRect.bottom - rRect.top;
wWi = rRect.right - rRect.left;
SendMessage(hWnd,WM_SIZE,SIZENORMAL,MAKELONG(wWi,wHi));
}
}
break;
case WM_GETTEXTLENGTH:
{
LPBYTE lpOtherData;
WORD wTextLen;
lpOtherData = (LPBYTE) LocalLock(OTHERDATA);
wTextLen = (WORD) *(lpOtherData + LABEL_LEN_OFFSET);
lResult = (LONG) wTextLen;
LocalUnlock(OTHERDATA);
}
break;
case WM_GETTEXT:
{
LPBYTE lpOtherData;
WORD wTextLen;
lpOtherData = (LPBYTE) LocalLock(OTHERDATA);
wTextLen = (int) *(lpOtherData + LABEL_LEN_OFFSET);
if (wParam < wTextLen)
wTextLen = wParam;
if (wTextLen > 0)
lstrncpy( (LPSTR) lParam, (lpOtherData + LABEL_TEXT_OFFSET), (int) wTextLen);
lResult = (LONG) wTextLen;
LocalUnlock(OTHERDATA);
}
break;
case WM_CLOSE:
{
DeleteObject(HILITERGN);
DeleteObject(SHADOWRGN);
DeleteObject(LABELRGN);
LocalFree(OTHERDATA);
lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
}
break;
case CRBM_SETFACEBRUSH:
{
if (wParam)
SET_FACEBRUSH(wParam);
else
SET_FACEBRUSH(hDefFaceBrush);
}
break;
case CRBM_SETSHADOWBRUSH:
{
if (wParam)
SET_SHADOWBRUSH(wParam);
else
SET_SHADOWBRUSH(hDefShadowBrush);
}
break;
case CRBM_SETTEXTCOLOR:
{
if (wParam)
SET_NORMALTEXTRGB(lParam);
else
SET_NORMALTEXTRGB(crDefNormalText);
}
break;
case CRBM_SETDRAWTEXTSTYLE:
{
SET_DRAWTEXTSTYLE(wParam & STRIP_BAD_DT_FLAG);
}
break;
case WM_SETFONT:
case CRBM_SETLABELFONT:
{
RECT rRect;
WORD wHi, wWi;
if (wParam)
SET_LABELFONT(wParam);
else
SET_LABELFONT(hDefLabelFont);
GetClientRect(hWnd, &rRect);
wHi = rRect.bottom - rRect.top;
wWi = rRect.right - rRect.left;
SendMessage(hWnd,WM_SIZE,SIZENORMAL,MAKELONG(wWi,wHi));
}
break;
case CRBM_GETFACEBRUSH:
{
HBRUSH hTmpBrush;
hTmpBrush = (HBRUSH) FACEBRUSH;
if (hTmpBrush == hDefFaceBrush)
hTmpBrush = NULL;
lResult = MAKELONG (hTmpBrush, 0);
}
break;
case CRBM_GETSHADOWBRUSH:
{
HBRUSH hTmpBrush;
hTmpBrush = (HBRUSH) SHADOWBRUSH;
if (hTmpBrush == hDefShadowBrush)
hTmpBrush = NULL;
lResult = MAKELONG (hTmpBrush, 0);
}
break;
case CRBM_GETTEXTCOLOR:
{
lResult = NORMALTEXTRGB;
}
break;
case CRBM_GETDRAWTEXTSTYLE:
{
lResult = MAKELONG (DRAWTEXTSTYLE, 0);
}
case WM_GETFONT:
case CRBM_GETLABELFONT:
{
HFONT hTmpFont;
hTmpFont = (HFONT) LABELFONT;
if (hTmpFont == hDefLabelFont)
hTmpFont = NULL;
lResult = MAKELONG (hTmpFont, 0);
}
break;
default : /* default window message processing */
lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
break;
}
/* return final result */
return( lResult );
}
/**/
/*
* ColorButtonDlgFn( hDlg, wMessage, wParam, lParam ) : BOOL;
*
* hDlg dialog box handle
* wMessage current window message
* wParam word parameter
* lParam long parameter
*
* This function is responsible for processing all the messages that
* relate to the style dialog box. This function transfers data
* between itself and the ColorButtonStyle using a global data handle.
*
* If the user presses the OK button, this data handle is used to pass
* back a new style data block. It is left to the calling routine to
* delete this new block.
*
*/
BOOL FAR PASCAL ColorButtonDlgFn(HWND hDlg,
WORD wMessage,
WORD wParam,
LONG lParam )
{
BOOL bResult;
/* initialization */
bResult = TRUE;
/* process message */
switch( wMessage ) {
case WM_INITDIALOG :
{
HANDLE hCtlStyle;
LPCTLSTYLE lpCtlStyle;
char szId[ 20 ]; /* temp. string to hold id */
/* disable Ok button & save dialog data handle */
hCtlStyle = hLibData;
EnableWindow( GetDlgItem(hDlg,IDOK), FALSE );
/* retrieve & display style parameters */
if ( hCtlStyle ) {
/* add handle to property list */
SetProp( hDlg, MAKEINTRESOURCE(1), hCtlStyle );
/* update dialog box fields */
lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );
SetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle );
/* Set the id value string correctly.
* Save the pointer to the verify id function from dialog editor
*/
if ( lpfnIdStr )
{
(*lpfnIdStr)(lpCtlStyle->wId, (LPSTR)szId, sizeof( szId ) );
SetDlgItemText( hDlg, IDVALUE, szId );
}
else {
EnableWindow( GetDlgItem( hDlg, IDVALUE ), FALSE );
}
CheckDlgButton(hDlg, 258, (WORD) (LOWORD(lpCtlStyle->dwStyle) & BS_DEFPUSHBUTTON));
lstrcpy( lpCtlStyle->szClass, COLORBUTTONCLASS );
SetProp( hDlg, IDFNHI, HIWORD( (DWORD)lpfnVerId ) );
SetProp( hDlg, IDFNLO, LOWORD( (DWORD)lpfnVerId ) );
GlobalUnlock( hCtlStyle );
}
else
EndDialog( hDlg, FALSE );
}
break;
case WM_COMMAND :
/* process sub-message */
switch( wParam ) {
case IDCANCEL : /* cancel dialog box */
RemoveProp( hDlg, MAKEINTRESOURCE(1) );
RemoveProp( hDlg, IDFNLO );
RemoveProp( hDlg, IDFNHI );
EndDialog( hDlg, FALSE );
break;
case IDOK : /* save dialog changes */
{
HANDLE hCtlStyle;
LPCTLSTYLE lpCtlStyle;
LPFNSTRTOID lpfnId; /* pointer to the verify id function from dialog editor */
char szId[ 20 ]; /* temp. string to hold the id */
hCtlStyle = GetProp( hDlg, MAKEINTRESOURCE(1) );
/* update structure contents */
lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );
szId[ 0 ] = NULL;
GetDlgItemText( hDlg, IDVALUE, szId, sizeof(szId) );
lpfnId = (LPFNSTRTOID)MAKELONG( GetProp( hDlg, IDFNLO ), GetProp( hDlg, IDFNHI ) );
if ( lpfnId ) {
DWORD dwResult; /* result ofthe verifyId function */
dwResult = (*lpfnId)( (LPSTR)szId );
if ( !(BOOL)dwResult ) {
/* Wrong id */
GlobalUnlock( hCtlStyle );
break;
}
lpCtlStyle->wId = HIWORD( dwResult );
if (IsDlgButtonChecked(hDlg, 258))
lpCtlStyle->dwStyle |= BS_DEFPUSHBUTTON;
else
lpCtlStyle->dwStyle |= BS_PUSHBUTTON;
}
GetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle, sizeof(lpCtlStyle->szTitle) );
GlobalUnlock( hCtlStyle );
RemoveProp( hDlg, MAKEINTRESOURCE(1) );
RemoveProp( hDlg, IDFNLO );
RemoveProp( hDlg, IDFNHI );
/* end dialog box */
hLibData = hCtlStyle;
EndDialog( hDlg, TRUE );
}
break;
case IDTEXT : /* control text */
case IDVALUE : /* control id */
/* enable or disable Ok button */
if ( HIWORD(lParam) == EN_CHANGE )
EnableWindow(GetDlgItem(hDlg,IDOK),
(SendMessage(GetDlgItem(hDlg,IDTEXT),WM_GETTEXTLENGTH,0,0L) &&
SendMessage(GetDlgItem(hDlg,IDVALUE),WM_GETTEXTLENGTH,0,0L)) ?
TRUE : FALSE);
break;
default : /* something else */
bResult = FALSE;
break;
}
break;
default :
bResult = FALSE;
break;
}
/* return final result */
return( bResult );
}
/**/
void ShowButtonDown(HANDLE hWnd)
{
SET_BUTTONISDOWN;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
void ShowButtonUp(HANDLE hWnd)
{
SET_BUTTONISUP;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
BOOL FAR PASCAL DrawLabel(HDC hDC, LPSTR lpLabelText, int nCount)
{
HANDLE hWnd;
hWnd = hDrawTextWnd;
DrawText(hDC, lpLabelText, nCount, &rDrawLabel, DRAWTEXTSTYLE);
return(TRUE);
}
void lstrncpy(LPSTR lpDest, LPSTR lpSrc, int n)
{
while (n--)
if(!(*lpDest++ = *lpSrc++))
return;
}